﻿using System;
using System.Data.OleDb;

namespace DIYS
{
    /// <summary>
    /// Configuration of which channels to log
    /// </summary>
    public struct LogStreamConfiguration
    {
        public bool Log_channel_0 { get; set; }
        public bool Log_channel_1 { get; set; }
        public bool Log_channel_2 { get; set; }
        public bool Log_channel_3 { get; set; }
        public bool Log_channel_4 { get; set; }
        
    }
    
    /// <summary>
    /// Logger that logs data to excel
    /// </summary>
    public class LogStream
    {

        #region fields
        /// <summary>
        /// Current message from the client
        /// </summary>
        private string _currentMessage = "";

        /// <summary>
        /// The file path for the source excel book
        /// </summary>
        private string _sourceFileName;

        /// <summary>
        /// Start time of logging started
        /// </summary>
        private DateTime _startTime;

        /// <summary>
        /// True if logging is startet
        /// </summary>
        private bool _started = false;

        /// <summary>
        /// Connects to the source excel workbook
        /// </summary>
        OleDbConnection m_ConnectionToExcelBook;

        #endregion

        #region properties
        /// <summary>
        /// Gets or Sets name of channel 0
        /// </summary>
        public string Channel_0_name { get; set; }

        /// <summary>
        /// Gets or Sets name of channel 1
        /// </summary>
        public string Channel_1_name { get; set; }

        /// <summary>
        /// Gets or Sets name of channel 2
        /// </summary>
        public string Channel_2_name { get; set; }

        /// <summary>
        /// Gets or Sets name of channel 3
        /// </summary>
        public string Channel_3_name { get; set; }

        /// <summary>
        /// Gets or Sets name of channel 4
        /// </summary>
        public string Channel_4_name { get; set; }

        /// <summary>
        /// Gets or Sets LogStreamConfiguration
        /// </summary>
        public LogStreamConfiguration Configuration { get; set; }
        
        /// <summary>
        /// Gets the current messages from the client
        /// </summary>
        public string CurrentMessage
        {

            get
            {
                return this._currentMessage;
            }

        }

        /// <summary>
        /// Gets or Sets the current source excel book
        /// </summary>
        public string FileName
        {

            get
            {
                return this._sourceFileName;
            }
            set
            {
                this._sourceFileName = value;
            }

        }


        public bool IsLogging { get; set; }
        #endregion

        #region Constructor

        /// <summary>
        /// Construtor
        /// </summary>
        public LogStream()
        {

            Configuration = new LogStreamConfiguration()
                                {   Log_channel_0 = true,
                                    Log_channel_1 = true,
                                    Log_channel_2 = true,
                                    Log_channel_3 = true,
                                    Log_channel_4 = true,
                                 };
        }


        #endregion

        #region methods

        /// <summary>
        /// Runs a non query database command such as UPDATE , INSERT or DELETE
        /// </summary>
        /// <param name="iQuery">The required query</param>
        /// <returns>true if succesfull</returns>
        public bool runNonQuery(string iQuery)
        {
            try
            {
                OleDbCommand nonQueryCommand = new OleDbCommand(iQuery);

                nonQueryCommand.Connection = this.m_ConnectionToExcelBook;
                nonQueryCommand.CommandText = iQuery;

                int rowsAffected = nonQueryCommand.ExecuteNonQuery();

                this._currentMessage = "SUCCESS - " + rowsAffected.ToString() + " Rows affected ";

                return true;
            }
            catch (Exception ex)
            {

                this._currentMessage = "ERROR " + ex.Message;
                return false;
            }
        }

        /// <summary>
        /// Opens the connection to the source excel document
        /// </summary>
        /// <returns>true if connection is open</returns>
        public bool openConnection(string iSourceFileName)
        {
            try
            {
                this._sourceFileName = iSourceFileName;
                this.m_ConnectionToExcelBook = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + this._sourceFileName + ";Extended Properties=Excel 8.0;");
                this.m_ConnectionToExcelBook.Open();
                CreateSheet();
                this._currentMessage = "SUCCESS - Connection to Source Established";

                IsLogging = true;
            }
            catch (Exception ex)
            {
                this._currentMessage = "ERROR " + ex.Message;
                IsLogging = false;
            }

            return IsLogging;

        }


        /// <summary>
        /// Closes the connection to the source excel document
        /// </summary>
        /// <returns>true is connection is closed</returns>
        public bool closeConnection()
        {
            try
            {
                this.m_ConnectionToExcelBook.Close();
                _started = false;
                this._currentMessage = "SUCCESS - Connection to Source Closed";
                IsLogging = false;
            }
            catch (Exception ex)
            {
                this._currentMessage = "ERROR " + ex.Message;
                //MessageBox.Show(ex.Message, "Error Closing Source", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        /// <summary>
        /// Creates a new excel sheet from the wanted configuration
        /// </summary>
        /// <returns>true if created</returns>
        private bool CreateSheet()
        {
            string query = "CREATE TABLE DIYSLog (SampleTime double";
            
            if(Configuration.Log_channel_0)
                query += ", " + Channel_0_name + " double";
            if(Configuration.Log_channel_1)
                query += ", " + Channel_1_name + " double";
            if(Configuration.Log_channel_2)
                query += ", " + Channel_2_name + " double";
            if(Configuration.Log_channel_3)
                query += ", " + Channel_3_name + " double";
            if(Configuration.Log_channel_4)
                query += ", " + Channel_4_name + " double";
            query+=");";

            return runNonQuery(query);
        }


        
        /// <summary>
        /// Adds values to the current excel sheet
        /// </summary>
        /// <param name="values">Values to be added</param>
        public void AddValues(string values)
        {
            if(!_started)
                _startTime = DateTime.Now;

            _started = true;

            TimeSpan timeSinceLast = DateTime.Now - _startTime; ;

            string[] value = values.Split(',');

            try
            {
                double value0 = ((double)Int32.Parse(value[0])) / 100;
                double value1 = ((double)Int32.Parse(value[1])) / 100;
                double value2 = ((double)Int32.Parse(value[2])) / 100;
                int value3 = (Int32.Parse(value[3]));
                int value4 = (Int32.Parse(value[4]));

                string query = "insert into [DIYSLog$] values(";

                query += "'" + timeSinceLast.TotalMilliseconds + "'";

                if (Configuration.Log_channel_0)
                    query += ", '" + value0 + "'";
                if (Configuration.Log_channel_1)
                    query += ", '" + value1 + "'";
                if (Configuration.Log_channel_2)
                    query += ", '" + value2 + "'";
                if (Configuration.Log_channel_3)
                    query += ", '" + value3 + "'";
                if (Configuration.Log_channel_4)
                    query += ", '" + value4 + "'";

                query += ")";

                runNonQuery(query);

            }
            catch { }
        }

        #endregion

    }
}
